package com.sos.core.cards
{
	
	import com.sos.utils.StringUtils;
	
	import flash.utils.getDefinitionByName;
	
	public class CardFactory
	{
		
		// TODO: fake class references to force FlashPlayer to load cards class definitions!
		// to remove!
		private static var player:PlayerCard;
		private static var action:ActionCard;
		private static var training:TrainingCard;
		private static var goalkeeper:GoalkeeperCard;
		
		
		private static const	JSON_PROPERTY_INSTANCE_LIST:String = "instanceList";
		
		// -------------------------------------------------------------------------------
		// PRIVATE METHODS
		// -------------------------------------------------------------------------------
		
		/**
		 * 
		 * @param type
		 * @return 
		 */		
		private static function getClassName(type:CardType):String
		{
			// return "com.soccertgc.data.cards." + StringUtils.capitalize(type.name.toLowerCase()) +  "Card";
			return "com.sos.core.cards." + StringUtils.capitalize(type.name.toLowerCase()) +  "Card";
		}
		
		/**
		 * Create an instance of the card for the given CardType without initializes
		 * it 
		 * @param type
		 * @return An instance of a Card for the given CardType
		 */		
		internal static function createEmptyCard(type:CardType, kind:CardKind = null):Card
		{
			// checks card kind
			kind = (kind != null) ? kind : CardKind.INSTANCE; 
			// Retrieve the class name
			var cardClassName:String = getClassName(type);
			// Create 
			var cardClass:Class = getDefinitionByName(cardClassName) as Class;
			// Dynamic class initialization!
			var cardInstance:Card = new cardClass(kind);
			// Returns the new instance
			return cardInstance;
		}
		
		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------

		/**
		 * Create an instance of the card for the given Cardtype and initializes
		 * it using data object provided 
		 * @param type CardType of the card to create
		 * @param data Object to use to initialize the new card instance
		 * @return An instance of the CardType class initialized with the given data
		 */		
		public static function createByKind(kind:CardKind, data:Object):Card
		{
			// Checks the card
			// Retrieve card type
			var type:CardType = CardType.getByObject(data);
			// Create the card
			var cardInstance:Card = createEmptyCard(type, kind);
			// Initializes the card
			cardInstance.load(data);
			// Returns the new instance loaded
			return cardInstance;
		}
		
		/**
		 * Create an instance of the card for the given Cardtype and initializes
		 * it using data object provided 
		 * @param type CardType of the card to create
		 * @param data Object to use to initialize the new card instance
		 * @return An instance of the CardType class initialized with the given data
		 */		
		public static function create(type:CardType, data:Object):Card
		{
			// Create the card
			var cardInstance:Card = createEmptyCard(type);
			// Initializes the card
			cardInstance.load(data);
			// Returns the new instance loaded
			return cardInstance;
		}
		
		/**
		 * 
		 * @param data
		 * @return  
		 */		
		public static function createActionCards(data:Object):Vector.<ActionCard>
		{
			// Instances list
			var instances:Array = data[JSON_PROPERTY_INSTANCE_LIST];
			// action cards list
			var cards:Vector.<ActionCard> = new Vector.<ActionCard>();
			// Create the card
			var cardInstance:Card = createEmptyCard(CardType.ACTION);
			// Initializes the card
			cardInstance.load(data);
			// Duplicates the template for each instance id
			for (var i:int = 0; i < instances.length; i++)
			{
				// Duplicates the card for each instanceId provided into the instances list
				cards.push(cardInstance.duplicate(cardInstance.kind, instances[i]) as ActionCard);
			}
			// Returns the action card list
			return cards;
		}
				
	}
}